#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb,
                                 const std::string &name)
    : loop_(nullptr), exiting_(false), thread_(std::bind(&EventLoopThread::threadFunc, this), name), mutex_(), cond_(), callback_(cb)
{
}

EventLoopThread::~EventLoopThread()
{
    exiting_ = true;
    if (loop_ != nullptr)
    {
        loop_->quit();
        thread_.join();
    }
}

/**
 * 启动线程：调用 thread_.start() 启动线程。
 * 等待事件循环创建完成：
 * 使用条件变量 cond_ 等待 loop_ 被初始化。
 * cond_.wait 会阻塞当前线程，直到 loop_ 被设置为非空。
 * 返回事件循环对象：返回初始化完成的 EventLoop 对象。
 */
EventLoop *EventLoopThread::startLoop()
{
    thread_.start(); // 启用底层线程Thread类对象thread_中通过start()创建的线程

    EventLoop *loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(mutex_);
        cond_.wait(lock, [this]()
                   { return loop_ != nullptr; });
        loop = loop_;
    }
    return loop;
}

/**
 * 下面这个方法 是在单独的新线程里运行的
 *
 * 创建事件循环：在新线程中创建一个 EventLoop 对象。
 * 执行初始化回调：如果用户定义了初始化回调函数 callback_，则调用它。
 * 通知主线程：
 * 使用互斥锁 mutex_ 和条件变量 cond_，将 loop_ 设置为当前线程的 EventLoop 对象。
 * 调用 cond_.notify_one()，通知主线程 loop_ 已经初始化完成。
 * 启动事件循环：调用 loop.loop()，启动事件循环。
 * 清理资源：事件循环结束后，将 loop_ 设置为 nullptr。
 */
void EventLoopThread::threadFunc()
{
    EventLoop loop; // 创建一个独立的EventLoop对象 和上面的线程是一一对应的 级one loop per thread

    if (callback_)
    {
        callback_(&loop);
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;
        cond_.notify_one();
    }
    loop.loop(); // 执行EventLoop的loop() 开启了底层的Poller的poll()
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}